package com.wsoft.sms.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.service.CommonAccountService;
import com.wsoft.core.service.CommonMemberService;
import com.wsoft.core.service.CommonOrgService;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.core.vo.AccountVO;
import com.wsoft.core.vo.MemberVO;
import com.wsoft.core.vo.OrganizationVO;
import com.wsoft.enums.MsgTypeEnum;
import com.wsoft.enums.PublishStatusEnum;
import com.wsoft.mq.constant.SmsConstant;
import com.wsoft.mq.vo.MessageVO;
import com.wsoft.sms.entity.SmsMessageEntity;
import com.wsoft.sms.entity.SmsMessageReadEntity;
import com.wsoft.sms.manager.MessageManager;
import com.wsoft.sms.manager.MessageReadManager;
import com.wsoft.sms.mapper.SmsMessageMapper;
import com.wsoft.sms.query.message.MessageInsertQuery;
import com.wsoft.sms.query.message.MessageListQuery;
import com.wsoft.sms.query.message.MessageUpdateQuery;
import com.wsoft.sms.service.ISmsMessageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wsoft.utils.RabbitMQUtil;
import com.wsoft.vo.LoginUserVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 消息表 服务实现类
 * </p>
 *
 * @author zhanggukai
 * @since 2025年01月02日 15:35:55
 */
@Service
public class SmsMessageServiceImpl extends ServiceImpl<SmsMessageMapper, SmsMessageEntity> implements ISmsMessageService {

    @Resource
    private MessageManager messageManager;
    @Resource
    private MessageReadManager readManager;
    @Resource
    private RabbitMQUtil rabbitMQUtil;
    @Resource
    private CommonOrgService commonOrgService;
    @Resource
    private CommonMemberService commonMemberService;
    @Resource
    private CommonAccountService commonAccountService;

    @Override
    public boolean insert(MessageInsertQuery query) {
        SmsMessageEntity entity = Convert.convert(SmsMessageEntity.class, query);
        entity.setSendStatus(PublishStatusEnum.NOT_PUBLISH.getType());
        return save(entity);
    }

    @Override
    public boolean update(MessageUpdateQuery query) {
        SmsMessageEntity message = getById(query.getId());
        if (PublishStatusEnum.PUBLISH.getType().equals(message.getSendStatus())) {
            //发布状态不允许修改
            Asserts.fail("[cms.publishStatus.error]");
        }
        //判断 当前状态,是否可以修改
        SmsMessageEntity entity = Convert.convert(SmsMessageEntity.class, query);
        return updateById(entity);
    }

    @Override
    public boolean delete(Long id) {
        return removeById(id);
    }

    @Override
    public SmsMessageEntity getMessage(Long id) {
        return getById(id);
    }

    @Override
    public SmsMessageEntity getMessageByMember(Long id) {
        MessageListQuery listQuery = new MessageListQuery();
        List<SmsMessageEntity> list = messageManager.listMessage(listQuery, true, id);
        if(CollUtil.isEmpty(list)){
            //无权限查看
            Asserts.fail("[cms.view.error]");
        }
        SmsMessageEntity entity = getById(id);
        readManager.read(id, LoginUserUtil.getUserInfo().getLoginUserVO().getId());
        return entity;
    }

    @Override
    public PageInfo<SmsMessageEntity> pageMessage(MessageListQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<SmsMessageEntity> list = messageManager.listMessage(query, false,null);
        return PageInfo.of(list);
    }

    @Override
    public List<SmsMessageEntity> listUnRead(MessageListQuery query) {
        List<SmsMessageEntity> list = messageManager.listMessage(query, true,null);
        if (CollUtil.isNotEmpty(list)) {
            LoginUserVO userVO = LoginUserUtil.getUserInfo().getLoginUserVO();
            //已读用户列表
            Set<Long> readMemberSet = readManager.getByMemberId(userVO.getId());
            list = list.stream().filter(item-> !readMemberSet.contains(item.getId())).collect(Collectors.toList());
            return list;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean release(Long id) {
        SmsMessageEntity entity = getById(id);
        if (PublishStatusEnum.PUBLISH.getType().equals(entity.getSendStatus())
                ) {
            //状态不正确
            Asserts.fail("[cms.publishStatus.error]");
        }
        if(null == entity.getSendTime() || null == entity.getSendMemberId() || null == entity.getSendOrgId()){
            //发布参数错误
            Asserts.fail("[cms.publish.param.error]");
        }
            //立即发布
            entity.setSendStatus(PublishStatusEnum.PUBLISH.getType());
            entity.setSendTime(LocalDateTime.now());
            entity.setSendMemberId(LoginUserUtil.getUserInfo().getLoginUserVO().getId());
            entity.setSendOrgId(LoginUserUtil.getUserInfo().getLoginUserVO().getLoginOrgId());
        boolean b = updateById(entity);
        if (b){
            MessageVO messageVO = new MessageVO();
            messageVO.setClientType(entity.getClientType());
            //处理发送人员
            List<Long> memberIds = getMemberIdsByType(entity.getMsgType(), entity.getMsgIds());
            List<AccountVO> accountList = commonAccountService.getAccountList();
            List<String> result = accountList.stream().filter(e -> e.getIsOnline().equals(0) && memberIds.contains(e.getMemberId()))
                    .map(AccountVO::getMemberId).map(Object::toString) .collect(Collectors.toList());
            messageVO.setMemberIdList(result);
            messageVO.setModule("SMS");
            messageVO.setData(JSONUtil.toJsonStr(entity));
            rabbitMQUtil.sendMessage(SmsConstant.SMS_TO_USER_DIRECT_EXCHANGE
                    , SmsConstant.SMS_TO_USER_KEY,
                    messageVO);
        }
        return b;
    }

    @Override
    public boolean withdraw(Long id) {
        SmsMessageEntity entity = getById(id);
        entity.setSendStatus(PublishStatusEnum.CANCEL.getType());
        entity.setCancelTime(LocalDateTime.now());
        return updateById(entity);
    }

    @Override
    public boolean allRead() {
        MessageListQuery query = new MessageListQuery();
        List<SmsMessageEntity> list = messageManager.listMessage(query, true,null);
        if(CollUtil.isNotEmpty(list)){
            LocalDateTime now = LocalDateTime.now();
            Long memberId = LoginUserUtil.getUserInfo().getLoginUserVO().getId();
            //已读用户列表
            Set<Long> readMemberSet = readManager.getByMemberId(memberId);
            List<SmsMessageReadEntity> readList = new ArrayList<>();
            list = list.stream().filter(item-> !readMemberSet.contains(item.getId())).collect(Collectors.toList());
            for (SmsMessageEntity entity : list) {
                SmsMessageReadEntity read = new SmsMessageReadEntity();
                read.setMessageId(entity.getId());
                read.setReadTime(now);
                read.setMemberId(memberId);
                read.setReadFlag(1);
                readList.add(read);
            }
            readManager.saveBatch(memberId,readList);
        }
        return true;
    }

    private List<Long> getMemberIdsByType(String msgType,String msgIds){
        List<OrganizationVO> allOrg = commonOrgService.getOrganizationAll();
        List<MemberVO> memberList = commonMemberService.getMemberList();
        List<Long> memberIds = new ArrayList<>();
        if (MsgTypeEnum.ORG.getType().equals(msgType)){
            String[] orgSplit = msgIds.split(",");
           for (String s : orgSplit) {
               OrganizationVO orgInfo = commonOrgService.getOrgInfo(Long.valueOf(s));
               List<Long> collect = allOrg.stream().filter(e -> e.getAuthCode().startsWith(orgInfo.getAuthCode()))
                       .map(OrganizationVO::getId).collect(Collectors.toList());
               memberIds = memberList.stream().filter(e -> collect.contains(e.getLoginOrgId())).map(MemberVO::getId).collect(Collectors.toList());
           }
        }
        if (MsgTypeEnum.POST.getType().equals(msgType)){
            List<Long> postIds =  Arrays.stream(msgIds.split(","))
                    .map(Long::parseLong)
                    .collect(Collectors.toList());
            memberIds = memberList.stream().filter(e -> postIds.contains(e.getCurPostId())).map(MemberVO::getId).collect(Collectors.toList());
        }
            if (MsgTypeEnum.LEVEL.getType().equals(msgType)){
                List<Long> levelIds =  Arrays.stream(msgIds.split(","))
                        .map(Long::parseLong)
                        .collect(Collectors.toList());
                memberIds = memberList.stream().filter(e -> levelIds.contains(e.getCurPostId())).map(MemberVO::getId).collect(Collectors.toList());
            }
            if (MsgTypeEnum.MEMBER.getType().equals(msgType)){
                memberIds =   Arrays.stream(msgIds.split(","))
                        .map(Long::parseLong)
                        .collect(Collectors.toList());
            }

        return memberIds;
    }
}
